﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace KZ400B
{
    public partial class AxleManager
    {
        /// <summary>
        /// 运行
        /// </summary>
        /// <param name="axleName"></param>
        /// <returns></returns>
        public static bool Run(string axleName
            , Axle.Direction dir
            , double period
            , double totalStep
            )
        {
            return Run(axleName, dir, period, totalStep, false);
        }

        /// <summary>
        /// 运行
        /// </summary>
        /// <param name="axleName"></param>
        /// <returns></returns>
        public static bool Run(string axleName
            , Axle.Direction dir
            , double period
            , double totalStep
            , bool force
            
            )
        {
            if (!IsOpen)
            {
                return false;
            }
            if (!AxleRunState.Instance.CanRun(axleName))
            {
                Data.AxleStateBarMsg.Instance.AxleState =
                    string.Format("[{0}]轴正在运行，请稍候再试!", axleName);
                return false;
            }
            //old way
            //if (ParameterSetting(axleName,dir,period,totalStep,force))
            //{
            //    string data = Protocol.Packet(
            //    Protocol.GetRunString(axleName)
            //    );
            //    return sendData(data);
            //}

            //new way
           if(AxleCacheManager.AxleList.ContainsKey(axleName))
           {
               AxleCacheManager.AxleList[axleName].TargetParametersSetting.RunAfterPMSetting = true;
               if (!force && ParameterCacheManager.Compare(axleName, dir, period, totalStep) 
                   && !AxleCacheManager.AxleList[axleName].AxleActionStatus.VZeroIsSeted)
               {
                   OnPMSettingRespond(axleName, true);
                   return true;
               }
               return ParameterSettingNew(axleName, dir, period, totalStep, force);
           }

           return false;

        }


        /// <summary>
        /// 运行
        /// </summary>
        /// <param name="axleName"></param>
        /// <returns></returns>
        public static bool Run(string axleName)
        {
            if (!IsOpen)
            {
                return false;
            }
            if (!AxleRunState.Instance.CanRun(axleName)) 
            { 
                Data.AxleStateBarMsg.Instance.AxleState = 
                    string.Format("[{0}]轴正在运行，请稍候再试!",axleName);
                return false;
            }
            //bool rst = false;
            string data = Protocol.Packet(
                Protocol.GetRunString(axleName)
                );
            return sendData(data);
            //try
            //{
            //    string msg = string.Empty;
            //    lock (s_spLocker)
            //    {
            //        if (spLink.CanWrite)
            //        {
            //            spLink.Write(data);
            //            msg = spLink.ReadString();
            //            //rst = handleNrmAck(FunctionCode.FCodeRun,axleName,msg,false)
            //            //    == CommResultCode.Success
            //            //    ;
            //            CommResultCode crcd = handleNrmAck(FunctionCode.FCodeRun, axleName, msg, false);
            //            while (crcd != CommResultCode.Success)
            //            {
            //                if (crcd == CommResultCode.WrongFrame)
            //                {
            //                    msg = spLink.ReadString(1);
            //                    if (string.IsNullOrEmpty(msg))
            //                    {
            //                        return false;
            //                    }
            //                    crcd = handleNrmAck(FunctionCode.FCodeRun, axleName, msg, false);
            //                }
            //                else
            //                {
            //                    break;
            //                }
            //            }
            //            rst = crcd == CommResultCode.Success;
            //            if (rst)
            //            {
            //                AxleCacheManager.AxleList[axleName].AxleStatus = AxleStatus.Running;
            //            }
            //        }
            //    }
            //    AxleRunState.Instance[axleName] = rst;
            //    if (OnAxleActionResponse != null)
            //    {
            //        OnAxleActionResponse(axleName
            //            , AxleCacheManager.getAxle(axleName)
            //            , AxleActions.Run
            //            , rst
            //            , string.Format("[{0}] 轴 运行响应: {1} {2} "
            //            , axleName, rst.ToString(), rst ? "-> 正在运行 ... " : string.Empty
            //            )
            //        );
            //    }
            //}
            //finally
            //{
            //    //setIsLocked(false);
            //}
            //return rst;
        }

        /// <summary>
        /// 运行
        /// </summary>
        /// <param name="axleNameList"></param>
        public static bool Run(  List<string> axleNameList)
        {
            if (!IsOpen)
            {
                return false;
            }
            //bool rst = false;
            string data = Protocol.Packet(
                Protocol.GetRunString(axleNameList)
                );
            return sendData(data);
            //try
            //{
            //    string msg = string.Empty;
            //    lock (s_spLocker)
            //    {
            //        if (spLink.CanWrite)
            //        {
            //            spLink.Write(data);
            //            msg = spLink.ReadString();
            //            rst = handleNrmAck(FunctionCode.FCodeRun,axleNameList[0],msg,false)
            //                == CommResultCode.Success
            //                ;
            //        }
            //    }
                
            //    if (OnAxleActionResponse != null)
            //    {
            //        OnAxleActionResponse(Axle.AllAxleName
            //            , AxleCacheManager.getAxle(Axle.AllAxleName)
            //            , AxleActions.Run
            //            , rst
            //            , string.Format("[{0}] 轴 运行响应: {1} {2} "
            //            , Axle.AllAxleName, rst.ToString(), rst ? "-> 正在运行 ... " : string.Empty
            //            )
            //        );
            //    }
            //}
            //finally
            //{
            //    //setIsLocked(false);
            //}
            //return rst;
        }


        public static bool RunIM(string axleName
            , Axle.Direction dir
            , double period
            , double totalStep
            , bool force

            )
        {
            bool rst = ParameterSetting(axleName, dir, period, totalStep, force);
            if (rst)
            {
                rst = RunIM(axleName);
            }
            return rst;
        }

        public static bool RunIM(string axleName)
        {
            bool rst = Run(axleName);
            if (rst)
            {
                rst = doRun(axleName);
            }
            return rst;
        }

        private static bool doRun(string axleName)
        {
            bool rst = false;
            lock (s_spLocker)
            {
                if (spLink.CanRead)
                {
                    string msg = spLink.ReadString(10);
                    if (string.IsNullOrEmpty(msg))
                    {
                        return false;
                    }
                    ProtocolV2.UnpacketResult ur = ProtocolV2.Unpack(msg);
                    rst = ur.Result && ur.Action == AxleActions.RunRespond;
                    if (!rst)
                    {
                        return rst;
                    }
                    OnRunRespond(ur);




                    msg = spLink.ReadString(240);
                    if (string.IsNullOrEmpty(msg))
                    {
                        return false;
                    }
                    ur = ProtocolV2.Unpack(msg);
                    rst = ur.Result && ur.Action == AxleActions.RunFinish;
                    if (!rst)
                    {
                        return false;
                    }
                    OnRunComplete(ur,true);



                    msg = spLink.ReadString(240);
                    if (string.IsNullOrEmpty(msg))
                    {
                        return false;
                    }
                    ur = ProtocolV2.Unpack(msg);
                    rst = ur.Result && ur.Action == AxleActions.QueryPositionFinish;
                    if (!rst)
                    {
                        return false;
                    }
                    OnQueryPositionComplete(ur);

                    return true;
                }
            }// link lock
            return false;
        }

        public static void OnRunRespond(ProtocolV2.UnpacketResult ur)
        {
            if (ur.Result
                    && ur.Action == AxleActions.RunRespond

                    )
            {
                if (AxleCacheManager.AxleList.ContainsKey(ur.AxleName))
                {
                    AxleCacheManager.AxleList[ur.AxleName].OtherAxleStatus = AxleActions.RunRespond;
                    AxleCacheManager.AxleList[ur.AxleName].AxleStatus = AxleStatus.Running;
                }
            }
            if (!ur.Result)
            {
                AxleCacheManager.AxleList[ur.AxleName].TargetParametersSetting.ResetRunState();
                if (AxleCacheManager.AxleList.ContainsKey(ur.AxleName))
                {
                    AxleCacheManager.AxleList[ur.AxleName].OtherAxleStatus = AxleActions.RunError;
                    AxleCacheManager.AxleList[ur.AxleName].AxleStatus = AxleStatus.Stoped;
                }
            }

           setState(
                string.Format("[{0}] 轴 运行命令响应 : {1} {2} "
                        , ur.AxleName
                        , ur.Result ? "正确" : "错误"
                        , ur.Result ? "-> 运行中 ... " : string.Empty
                        )
                        );
        }
        public static void OnRunComplete(ProtocolV2.UnpacketResult ur)
        {
            OnRunComplete(ur,false);
        }
        public static void OnRunComplete(ProtocolV2.UnpacketResult ur,bool im)
        {
            if (ur.Result
                && ur.Action == AxleActions.RunFinish

                )
            {

                AxleRunState.Instance[ur.AxleName] = false;
                if (AxleCacheManager.AxleList.ContainsKey(ur.AxleName))
                {

                    //if (im)
                    //{ QueryPositionIM(ur.AxleName); }
                    //else
                    //{
                    //    QueryPosition(ur.AxleName);
                    //}
                    //Thread.Sleep(100);
                }

                if (AxleCacheManager.AxleList.ContainsKey(ur.AxleName))
                {
                    
                }

                //如果是连续点击单步运行位置的话，则继续
                if (AxleCacheManager.AxleList[ur.AxleName].TargetParametersSetting.RunType == Axle.RunType.Consequent
                    && AxleCacheManager.AxleList[ur.AxleName].TargetParametersSetting.NeedRun
                    )
                {
                    Thread.Sleep(100);
                    Run(ur.AxleName);
                }
                else
                {
                    AxleCacheManager.AxleList[ur.AxleName].OtherAxleStatus = AxleActions.RunFinish;
                    AxleCacheManager.AxleList[ur.AxleName].AxleStatus = AxleStatus.Stoped;
                }
            }
            if (!ur.Result)
            {
                AxleCacheManager.AxleList[ur.AxleName].TargetParametersSetting.ResetRunState();
                if (AxleCacheManager.AxleList.ContainsKey(ur.AxleName))
                {
                    AxleCacheManager.AxleList[ur.AxleName].OtherAxleStatus = AxleActions.RunError;
                    AxleCacheManager.AxleList[ur.AxleName].AxleStatus = AxleStatus.Stoped;
                }
            }

            //AxleCacheManager.AxleList[ur.AxleName].AxleStatus = AxleActions.RunFinish;

            setState(
                string.Format("[{0}] 轴 运行命令运行结束 : {1}"
                        , ur.AxleName
                        , ur.Result ? "正确" : "错误"
                        )
                        );
        }

       
    }
}
